package com.project.seckill.service.impl;

import com.project.seckill.constant.CacheConstant;
import com.project.seckill.service.SeckillService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisClusterConnection;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author shenguangyang
 * @date 2022-09-02 20:26
 */
@Service
public class SeckillServiceImpl implements SeckillService {
    private static final Logger log = LoggerFactory.getLogger(SeckillServiceImpl.class);
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private DefaultRedisScript<Long> stockScript;

    @Override
    public boolean doSeckillByLua(Long userId, Long goodsId) {
        String goodsKey = String.format(CacheConstant.GOODS_STOCK_KEY, goodsId);
        List<String> keys = new ArrayList<>();
        keys.add(goodsKey);
        keys.add(CacheConstant.GOODS_STOCK_HASH_KEY);
        Long goodsStock = redisTemplate.execute(stockScript, keys);
        if (goodsStock == null || goodsStock <= 0) {
            log.warn("goods [{}] stock remaining is 0", goodsId);
            return false;
        }

        log.info("goods [{}] stock remaining is [{}]", goodsId, goodsStock);
        return true;
    }

    @Override
    public boolean doSeckillByLuaAndSegment(Long userId, Long goodsId) {
        RedisClusterConnection clusterConnection = Objects.requireNonNull(redisTemplate.getConnectionFactory()).getClusterConnection();
        Iterable<RedisClusterNode> redisClusterNodes = clusterConnection.clusterGetNodes();
        for (RedisClusterNode item : redisClusterNodes) {
            System.out.println(item.getHost() + ":" + item.getPort());
        }

        return false;
    }
}
